﻿using System;
using System.Collections.Generic;
using System.IO;
namespace Codemonk.Updater.Server
{
    internal static class FileReader
    {
        private static readonly object sync = new object();
        /// <summary>
        /// 限定的升级清单文件
        /// </summary>
        private const string InventoryFile = "codemonk.updater.inventory.xml";
        internal static Stream ReadFile(string appid, string filename)
        {
            var workdir = ServerConfig.WorkDir;
            var appdir = Path.Combine(workdir, appid);
            if (!Directory.Exists(appdir)) return null;
            var dirs = new DirectoryInfo(appdir).GetDirectories();
            if (dirs == null) return null;
            DirectoryInfo newest = dirs[0];
            var length = dirs.Length;
            for (int i = 1; i < length; i++)
            {
                var dir = dirs[i];
                if (dir.CreationTime > newest.CreationTime) newest = dir;
            }
            var basedir = newest.FullName;
            var basedirLength = basedir.Length + 1;
            var configdir = Path.Combine(basedir, ServerConfig.ConfigDir);
            if (!Directory.Exists(configdir)) return null;
            var entryfile = Path.Combine(configdir, ServerConfig.EntryFile);
            if (!File.Exists(entryfile)) return null;
            var inventoryfile = Path.Combine(configdir, InventoryFile);
            if (!File.Exists(inventoryfile))
            {
                lock (sync)
                {
                    if (!File.Exists(inventoryfile))
                    {
                        var entryPoint = File.ReadAllText(entryfile).Trim();
                        var files = newest.GetFiles("*.*", ServerConfig.SearchOption);
                        var compulsivefile = Path.Combine(configdir, ServerConfig.CompulsiveFile);
                        var updatelistfile = Path.Combine(configdir, ServerConfig.UpdatelistFile);
                        List<InventoryFileItem> items = new List<InventoryFileItem>();
                        foreach (var file in files)
                        {
                            var fullpath = file.FullName;
                            if (fullpath == entryfile || fullpath == updatelistfile || fullpath == inventoryfile || fullpath == compulsivefile) continue;
                            var name = fullpath.Substring(basedirLength);
                            if (!ServerConfig.SearchPattern.IsMatch(name)) continue;
                            var hash = FileHashHelper.ComputeHash(fullpath);
                            items.Add(new InventoryFileItem { Hash = hash, Name = name, Size = file.Length });
                        }
                        if (items.Count == 0) return null;
                        WriteInventory.Write(inventoryfile, new Inventory
                        {
                            IsCompulsive = File.Exists(compulsivefile),
                            UpdateList = File.Exists(updatelistfile) ? File.ReadAllText(updatelistfile) : ServerConfig.EmptyDescrption,
                            EntryPoint = entryPoint,
                            Items = items.ToArray()
                        });
                    }
                }
            }
            if (string.IsNullOrEmpty(filename)) filename = inventoryfile;
            else filename = Path.Combine(basedir, filename);
            return File.Exists(filename) ? File.Open(filename, FileMode.Open) : null;
        }
    }
}
